package oneD.models;

//import inf.v3d.view.Viewer;
import oneD.dynamics.DynamicStructure;
import oneD.dynamics.LinearTimeIntegrator;
import oneD.fem.Constraint;
import oneD.fem.Force;
import oneD.fem.Node;
import oneD.fem.structure.Structure;
import oneD.fem.structure.Truss;
import oneD.fem.visualize.DynamicTrussVisualizer;
import oneD.fem.visualize.TrussVisualizer;
import inf.jlinalg.BLAM;
import inf.jlinalg.IVector;
import inf.jlinalg.MatrixFormat;
import inf.jlinalg.SolveFailedException;
import inf.v3d.view.Viewer;

public class SmallTetraeder extends ModelViewer {

	@Override
	public Truss createStructure() {
		Truss struct = new Truss();
		double lb = 15.0;
		double r = 457.2 / 2000;
		double t = 10.0 / 1000;
		double a = Math.PI * (Math.pow(r, 2) - Math.pow(r - t, 2));
		double e = 2.1e11;
		Constraint c1 = new Constraint(false, false, false);
		Constraint c2 = new Constraint(true, true, false);
		Force f = new Force(0, -20e3, -100e3);
		// create nodes
		Node n1 = struct.addNode(0.0, 0.0, lb * Math.sqrt(2.0 / 3.0));
		Node n2 = struct.addNode(0.0, lb / Math.sqrt(3), 0);
		Node n3 = struct.addNode(-lb / 2, -lb / Math.sqrt(12.0), 0);
		Node n4 = struct.addNode(lb / 2, -lb / Math.sqrt(12.0), 0);
		// apply BCs
		n1.setForce(f);
		n2.setConstraint(c1);
		n3.setConstraint(c1);
		n4.setConstraint(c2);
		// create elements
		struct.addElement(1, e, a, 0, 1);
		struct.addElement(1, e, a, 0, 2);
		struct.addElement(1, e, a, 0, 3);
		struct.addElement(1, e, a, 1, 2);
		struct.addElement(1, e, a, 2, 3);
		struct.addElement(1, e, a, 3, 1);
		// return the new structure
		return struct;
	}

	@Override
	public void initializeVisualizer(Structure struct) {
		this.view_ = new Viewer();
		viz_ = new TrussVisualizer(struct, this.view_);
	}

	@Override
	public void initializeVisualizer(DynamicStructure dStruct) {
		this.view_ = new Viewer();
		viz_ = new DynamicTrussVisualizer(dStruct, this.view_);
	}

	@Override
	protected void performLinearDynamicAnalysis(Structure struct) {
		/*
		 * perform dynamic simulation
		 */
		System.out.println("Dynamic analysis");
		struct.solve();
		DynamicStructure dStruct = new DynamicStructure(struct);
		IVector u0 = dStruct.getStaticDisplacementVector();

		System.out.println("Static displacement vector:");
		System.out.println(MatrixFormat.format(u0));

		LinearTimeIntegrator TI = new LinearTimeIntegrator(dStruct);
		TI.setAlpha1(200);
		TI.setAlpha2(0);
		TI.setTimeStep(1e-5);
		TI.Initialize((int) (1e-2 / TI.getTimeStep()));
		TI.setAccelerationComplementaryConditionAtInitial(true);

		dStruct.addDisplacement(u0);
		IVector temp = (IVector) u0.clone();
		BLAM.fill(temp, 0);
		dStruct.addVelocity(temp);
		// does not need to set the acceleration since the
		// ComplementaryConditionAtInitial is set to true

		// TI.freeVibCDM();
		// TI.freeVibDG1();
		// TI.freeVibDG2();
		TI.freeVibDG(6);

		// dStruct.print();

		// Plot1D p = dStruct.plot();
		// p.setVisible(true);

		// Viewer v1 = new Viewer();
		// FunctionPlotter1D fp1 = dStruct.plot1combination(new int[] { 0 },
		// new String[] { "x", "y", "z" }, new String[] { "" });
		// fp1.plot(v1);
		// v1.setVisible(true);
		//
		// Viewer v2 = new Viewer();
		// FunctionPlotter1D fp2 = dStruct.plot2(0, "y");
		// fp2.plot(v2);
		// v2.setVisible(true);

		System.out.println("Visualize dynamic structure");
		this.initializeVisualizer(dStruct);
		// this.postVisualize();
		this.dynamicVisualize(dStruct);
		this.enableVisualize();
	}

	@Override
	protected void performNonlinearStaticAnalysis(Structure struct) {
		/*
		 * nonlinear static deformation solution
		 */
		System.out
				.println("This functionality is not supported for this model");
	}

	@Override
	protected void performNonlinearInstabilityAnalysisUsingSecondOrderTheory(
			Structure struct) {
		/*
		 * nonlinear static deformation solution
		 */
		System.out
				.println("This functionality is not supported for this model");
	}

	@Override
	protected void performNonlinearInstabilityAnalysisUsingDirectComputation(
			Structure struct) {
		/*
		 * nonlinear static deformation solution
		 */
		System.out
				.println("This functionality is not supported for this model");
	}

	@Override
	protected void performLoadDisplacementAnalysisUsingArcLength(
			Structure struct) {
		/*
		 * nonlinear static deformation solution
		 */
		System.out
				.println("This functionality is not supported for this model");
	}

	public static void main(String[] args) throws SolveFailedException {
		SmallTetraeder model = new SmallTetraeder();
		model.processUserInput();

	}
}
